home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 2
/
CU Amiga Magazine's Super CD-ROM 02 (1996)(EMAP Images)(GB)[!][issue 1996-04].iso
/
magazine
/
amiga_e
/
cardadd.e
< prev
next >
Wrap
Text File
|
1994-04-06
|
7KB
|
305 lines
MODULE 'workbench/startup', 'dos/dos', 'utility/date', 'utility'
CONST MEMSTART=$600000, BLOCKSIZE=$100, FILEINFOSIZE=$20, MAGIC=$2000
CONST HEADEROFF=2*BLOCKSIZE, BLKPTRSIZE=2, FILELEN=13, DEL=0, START=0
CONST FREEOFF=HEADEROFF+BLOCKSIZE, HEADER=HEADEROFF+MEMSTART
CONST FREEBLOCKS=FREEOFF+MEMSTART, EOFB=$FFFE, EOC=$FFFF, LEN=FILELEN-1
CONST SECSPERDAY=24*60*60
ENUM NO_ERR, BAD_CARD, NO_FREE, IN_USE, W_PROTECT, SHORT_FILE, DUP_FILE,
OPEN_ERR, EXAM_ERR, BAD_DIR, TOO_BIG, OPEN_LIB
ENUM FORCE, FILES
OBJECT fileinfo
file, next
ENDOBJECT
RAISE EXAM_ERR IF ExamineFH()=NIL,
OPEN_ERR IF Open()=NIL,
OPEN_LIB IF OpenLibrary()=NIL
/* lastinfo is a block pointer with MAGIC, e.g., $213A (not $13A) */
DEF thefiles:PTR TO fileinfo, lastfile:PTR TO fileinfo, lastinfo
PROC main() HANDLE
DEF startup:PTR TO wbstartup, wargs:PTR TO wbarg, oldlock=NIL,
templ, rdargs=NIL, args:PTR TO LONG, i, err
utilitybase:=OpenLibrary('utility.library', 37)
getinfo()
IF (startup:=wbmessage)=NIL
templ:='FORCE/S,FILE/M'
args:=[0,0]
rdargs:=ReadArgs(templ,args,NIL)
IF rdargs
IF (err:=checkwrite(args[FORCE]))<>NO_ERR THEN Raise(err)
IF args:=args[FILES]
WHILE args[] /* Loop through arguments */
addfile(args[])
args++
ENDWHILE
ENDIF
ENDIF
ELSE
wargs:=startup.arglist
wargs++
FOR i:=1 TO startup.numargs-1 /* Loop through the arguments */
IF wargs.lock=NIL
addfile(wargs.name)
ELSE
oldlock:=CurrentDir(wargs.lock)
addfile(wargs.name)
CurrentDir(oldlock) /* Important: restore current dir */
oldlock:=NIL
ENDIF
wargs++
ENDFOR
ENDIF
Raise(NO_ERR)
EXCEPT
setwrite()
IF oldlock THEN CurrentDir(oldlock)
IF rdargs THEN FreeArgs(rdargs)
IF utilitybase THEN CloseLibrary(utilitybase)
SELECT exception
CASE OPEN_LIB
WriteF('Cannot open utility library\n')
CASE BAD_CARD
WriteF('No PCMCIA card, or not from Notepad\n')
CASE IN_USE
WriteF('PCMCIA card is in use, or not from Notepad\n')
CASE W_PROTECT
WriteF('No PCMCIA card, or write protected\n')
CASE NO_FREE
WriteF('No more free blocks -- card is full\n')
ENDSELECT
ENDPROC
PROC addfile(fname) HANDLE
DEF fh=NIL, file, b=START, next, len, i=0, going=TRUE,
f:PTR TO fileinfo, found=NIL, name, fib:fileinfoblock
fh:=Open(fname, OLDFILE)
name:=FilePart(fname)
ExamineFH(fh, fib)
IF fib.direntrytype>0 THEN Raise(BAD_DIR)
len:=fib.size
IF (len<=0) OR (len>$FFFF) THEN Raise(TOO_BIG)
f:=thefiles.next
WHILE f
IF deleted(f.file)
IF found=NIL THEN found:=f.file
ELSE
IF equal(name, filename(f.file)) THEN Raise(DUP_FILE)
ENDIF
f:=f.next
ENDWHILE
IF found
file:=found
ELSE
file:=FILEINFOSIZE+lastfile.file
IF Mod(file, BLOCKSIZE)=0
IF (b:=findfree(b))=EOFB THEN Raise(NO_FREE)
initblock(b)
useblock(lastinfo, b)
lastinfo:=b
useblock(b, EOC)
file:=address(b)
ENDIF
ENDIF
IF (b:=findfree(b))=EOFB THEN Raise(NO_FREE)
lastfile.next:=newfile(file)
lastfile:=lastfile.next
setfirstblock(file, b)
setname(file, name)
setdate(file, fib.datestamp)
going:=TRUE
WHILE (i<len) AND going
Read(fh, address(b), BLOCKSIZE)
i:=i+BLOCKSIZE
IF (next:=findfree(b))=EOFB
going:=FALSE
ELSE
useblock(b, next)
b:=next
ENDIF
ENDWHILE
useblock(b, EOC)
IF going=FALSE THEN Raise(SHORT_FILE)
setsize(file, len)
Raise(NO_ERR)
EXCEPT
IF fh THEN Close(fh)
SELECT exception
CASE BAD_DIR
WriteF('"\s" is a directory\n', fname)
CASE TOO_BIG
WriteF('File "\s" is too large (or empty)\n', fname)
CASE OPEN_ERR
WriteF('Unable to open file "\s"\n', fname)
CASE EXAM_ERR
WriteF('Examine failed on "\s"\n', fname)
CASE DUP_FILE
WriteF('File "\s" already exists as "\s"\n', fname, filename(f.file))
CASE NO_FREE
Raise(NO_FREE)
CASE SHORT_FILE
setsize(file, i)
WriteF('File "\s" will be short\n', fname)
Raise(NO_FREE)
ENDSELECT
ENDPROC
PROC getinfo()
DEF info, nofiles=FALSE, atend=FALSE, file, d
file:=HEADER
lastinfo:=firstblock(file)
thefiles:=lastfile:=newfile(file)
IF validate(file)
d:=filedate(file)
file:=file+FILEINFOSIZE
REPEAT /* for all info blocks */
REPEAT /* for all files */
IF blank(file)
nofiles:=TRUE
ELSE
lastfile.next:=newfile(file)
lastfile:=lastfile.next
d:=filedate(file)
file:=file+FILEINFOSIZE
IF Mod(file, BLOCKSIZE)=0 THEN atend:=TRUE
ENDIF
UNTIL atend OR nofiles
IF atend
info:=follow(lastinfo)
IF (info<>EOC) AND (info<>DEL)
lastinfo:=info
file:=address(lastinfo)
atend:=FALSE
ELSE
nofiles:=TRUE
ENDIF
ENDIF
UNTIL nofiles
ELSE
Raise(BAD_CARD)
ENDIF
ENDPROC
PROC checkwrite(force)
DEF err=NO_ERR, p
p:=HEADER+12
Forbid()
IF (p[]=0) OR force
p[]:=0
IF p[]<>0 THEN err:=W_PROTECT
p[]:=1
IF p[]<>1 THEN err:=W_PROTECT
ELSE
err:=IN_USE
ENDIF
Permit()
ENDPROC err
PROC setwrite()
DEF p
p:=HEADER+12
Forbid()
p[]:=0
Permit()
ENDPROC
PROC equal(s, t)
DEF a[LEN]:STRING, b[LEN]:STRING
StrCopy(a, s, ALL)
StrCopy(b, t, ALL)
UpperStr(a)
UpperStr(b)
RETURN StrCmp(a, b, ALL)
ENDPROC
PROC follow(block) RETURN int(blockaddr(block))
PROC blockaddr(block) RETURN (block-MAGIC)*BLKPTRSIZE+FREEBLOCKS
PROC blockptr(addr) RETURN (addr-FREEBLOCKS)/BLKPTRSIZE+MAGIC
PROC address(block) RETURN (block-MAGIC)*BLOCKSIZE+MEMSTART
PROC useblock(block, next)
putint(blockaddr(block), next)
ENDPROC
PROC initblock(block)
DEF p, i
p:=address(block)
FOR i:=1 TO BLOCKSIZE DO p[]++:=0
ENDPROC
PROC validate(file)
RETURN StrCmp(filename(file), 'NC', 2) AND (firstblock(file)=HEADEROFF+MAGIC)
ENDPROC
PROC blank(file)
DEF n
FOR n:=0 TO FILEINFOSIZE-1 DO IF file[]++<>0 THEN RETURN FALSE
ENDPROC TRUE
PROC newfile(ptr)
DEF p
CopyMem([ptr, NIL]:fileinfo, p:=New(SIZEOF fileinfo), SIZEOF fileinfo)
ENDPROC p
PROC findfree(block)
DEF p, b
p:=IF block<>START THEN blockaddr(block+1) ELSE FREEBLOCKS
WHILE (b:=int(p))<>EOFB
IF b=0 THEN RETURN blockptr(p)
p:=p+BLKPTRSIZE
ENDWHILE
RETURN EOFB
ENDPROC
PROC setname(file, name)
DEF i, p
p:=file
FOR i:=0 TO FILELEN DO p[]++:=0
i:=StrLen(name)
CopyMem(name, file, IF i>=FILELEN THEN FILELEN-1 ELSE i)
ENDPROC
PROC setdate(file, ds:PTR TO datestamp)
DEF secs, cd:clockdata, date
secs:=Mul(ds.days,SECSPERDAY)+(ds.minute*60)+(ds.tick/50)
Amiga2Date(secs, cd)
date:=Shl(cd.year-1990, 25) OR Shl(cd.month, 21) OR Shl(cd.mday, 16) OR
Shl(cd.hour, 11) OR Shl(cd.min, 5)
putlong(file+16, date)
ENDPROC
PROC setsize(file, size)
putint(file+14, size)
ENDPROC
PROC setfirstblock(file, block)
putint(file+20, block)
ENDPROC
PROC putint(p, v)
p[]++:=v AND $FF
p[]:=Shr(v, 8) AND $FF
ENDPROC
PROC putlong(p, v)
p[]++:=v AND $FF
p[]++:=Shr(v, 8) AND $FF
p[]++:=Shr(v, 16) AND $FF
p[]:=Shr(v, 24) AND $FF
ENDPROC
PROC deleted(file) RETURN file[]=0
PROC filename(file) RETURN file
/*
PROC size(file) RETURN int(file+14)
*/
PROC filedate(file) RETURN long(file+16)
PROC firstblock(file) RETURN int(file+20)
PROC int(p) RETURN p[]++ OR Shl(p[],8)
PROC long(p) RETURN p[]++ OR Shl(p[]++,8) OR Shl(p[]++,16) OR Shl(p[],24)